#OpenMV的屏幕驱动示例不长，直接贴在这了
from time import sleep
from pyb import Pin, SPI, Timer
import display
from sensor import alloc_extra_fb,RGB565

#屏幕库声明
lcd = display.SPIDisplay(width=320,height=240, triple_buffer=True,refresh=60)

spi2 = SPI(2,SPI.MASTER,baudrate=75*1000000,phase=1)

#根据实际端口修改
LCD_CS = Pin('PB12', Pin.OUT_PP)
LCD_RST = Pin('PH6', Pin.OUT_PP)
LCD_RS = Pin('PH7', Pin.OUT_PP)

#屏幕背光，根据实际端口修改
LCD_BL_TIMER = Timer(3, freq=1000)  # Frequency in Hz
LCD_BL_PWM = LCD_BL_TIMER.channel(1, Timer.PWM, pin=Pin("PB4"), pulse_width_percent=0)

#设置屏幕背光
def backlight(value):
    LCD_BL_PWM.pulse_width_percent(value)

FORWARD = True
REVERSE = False
#初始化屏幕，默认横向，屏幕下巴向左

def init(orientation = FORWARD):
    commands = [
            (0x36, [0x28]),  # 存储器访问控制，设置扫描方向和RGB顺序等
            (0x3A, [0x55]),  # 设置像素格式，此处为16位色深
            (0xB4, [0x01]),  # 显示反向控制，设置行列交换等
            (0xB1, [0x80, 0x10]),  # 帧率控制，在正常模式下
            (0xB2, [0x0C, 0x0C, 0x00, 0x33, 0x33]),  # Porch控制，设置前/后廊
            (0xB5, [0x1F, 0x50, 0x00, 0x20]),  # 显示功能控制
            (0xB6, [0x8A, 0x07, 0x3B]),  # 显示功能设置，包括驱动方向等
            (0xB7, [0x46]),  # Gate控制，设置门电压级别
            (0xBB, [0x1B]),  # VCOM设置，调整公共电压
            (0xC3, [0x0F]),  # VRH设置，设置参考电压
            (0xC4, [0x20]),  # VDV设置，调节DV电压
            (0xC0, [0x80, 0x64]),  # 电源控制，提供电源操作模式设置
            (0xC1, [0x13]),  # 电源控制2，调节步进电压
            (0xC2, [0xA7]),  # 电源控制3，提供更多电源设置
            (0xC5, [0x09]),  # VCM控制，设置VCOMH电压
            (0xC6, [0x0F]),  # 帧速控制，设置屏幕刷新率
            (0xD0, [0xA4, 0xA1]),  # 电源控制1，调整AVDD和AVCL
            (0xD6, [0xA1]),  # 电源控制2，更多电源调节
            (0xE8, [0x40, 0x8a, 0x00, 0x00, 0x29, 0x19, 0xA5, 0x33]),  # 时序控制，调整内部时序设置
            (0xE0, [0xF0, 0x00, 0x06, 0x04, 0x05, 0x05, 0x31, 0x44, 0x48, 0x36, 0x12, 0x12, 0x2B, 0x34]),  # 正向Gamma控制，用于颜色校准
            (0xE1, [0xF0, 0x0B, 0x0F, 0x0F, 0x0D, 0x26, 0x31, 0x43, 0x47, 0x38, 0x14, 0x14, 0x2C, 0x32]),  # 反向Gamma控制，用于颜色校准
            (0x2A, [0x00, 0x00, 0x01, 0x3F]),  # 设置列地址，定义列范围（320像素宽）
            (0x2B, [0x00, 0x00, 0x00, 0xEF]),  # 设置行地址，定义行范围（240像素高）
            (0x35, [0x00]),  # 扫描行设置，使能部分行扫描
            (0x11, []),  # 退出睡眠模式命令
            (0x29, []),  # 显示开启命令
            (0x21, [])  # 显示反转命令
        ]

    for cmd, data in commands:
        write_c(cmd)
        for d in data:
            write_d(d)
        if cmd in (0x11, 0x29):  # Commands that require a delay
            sleep(0.12 if cmd == 0x11 else 0.05)

    backlight(80)
    set_orientation(orientation)

def write_c(c):
    try:
        LCD_CS.low()
        LCD_RS.low()
        spi2.send(c)
        LCD_CS.high()
    except:
        LCD_CS.high()

def write_d(c):
    try:
        LCD_CS.low()
        LCD_RS.high()
        spi2.send(c)
        LCD_CS.high()
    except:
        LCD_CS.high()

#画面180度翻转
display_inverted = True #显示反向，默认正向
def set_orientation(orientation=FORWARD):
    global display_inverted
    display_inverted = orientation
    write_c(0x36)  # 访问内存数据访问控制寄存器
    if orientation:
        write_d(0x28)  # 反向（180度倒转）
    else:
        write_d(0xE8)  # 正向

#显示
def display(img):
    lcd.write(img)

'''
在main中使用：
import screen
screen.init()
.....
.....
screen.display(img)
'''
